#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    //Qt中如果要让某个类能够使用信号槽(可以在类中定义信号和槽函数)
    //则必须要在类最开始的地方，写下Q_OBJECT宏.
    //这是Qt中的硬性规定
    //Q_OBJECT这个宏能展开成很多额外的代码
    //如果不加这个宏，这个类在编译的时候也会出错,当然如果不使用信号和槽,那么自然也就没有问题
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void myHandleSignal1();

    //信号（Signals）
    //信号是一个由对象发出的消息，表明发生了某个事件或特定条件已经成立。
    //信号是由对象的特定事件触发的，例如按钮被点击或者计时器超时。信号只有定义，不能自己实现，默认qt实现,它相当于一个通知系统，告诉外界某个事件已经发生。

    //Qt中也允许自定义信号.自定义槽函数，非常关键.开发中大部分情况都是需要自定义槽函数的槽函数
//    就是用户触发某个操作之后，要进行的业务逻辑
//    自定义信号，比较少见.实际开发中很少会需要自定义信号.信号就对应到用户的某个操作
//    在GUI,用户能够进行哪些操作，是可以穷举的
//    Qt内置的信号，基本上已经覆盖到了上述所有可能的用户操作
    //因此，使用Qt内置的信号，就足以应付大部分的开发场景了

    //作为信号函数，这个函数的返回值，必须是void.有没有参数都可以.甚至也可以支持重载
    //signals:这个也是Qt自己扩展出来的关键字,所有自定义信号,都要写在这里面
signals:
    void mySignal1();

    //信号和槽也可以带参数.当信号带有参数的时候，槽的参数必须和信号的参数一致
    //一致主要是要求类型.个数如果不一致也可以不一致的时候
    //要求信号的参数的个数必须要比槽的参数个数要更多,同时从槽函数左往右的的参数类型必须和信号的类型保持一致
    //此时发射信号的时候，就可以给信号函数传递实参.与之对应的这个参数就会被传递到对应的槽函数中.此时就可以起到让信号给槽传参效果了.
    //传参可以起到复用代码的效果有多个逻辑，逻辑上整体一致，但是涉及到的数据不同就可以通过函数参数来复用代码，并且在不同的场景中传入不同的参数即可
    //信号函数的参数个数，超过了槽函数的参数个数，此时，都是可以正常使用的
    //信号函数的参数个数，少于槽函数的参数个数，此时代码无法编译通过

    //直观的思考，应该是要求信号的参数个数和槽的参数个数，严格一致,此处为啥允许信号的参数比槽的参数多呢？
    //一个槽函数，有可能会绑定多个信号，如果我们严格要求参数个数一致，就意味着信号绑定到槽的要求就变高了
    //换而言之，当下这样的规则，就允许信号和槽之间的绑定更灵活了.更多的信号可以绑定到这个槽函数上了
    void mySignal2(const QString& text, int number, const QString& text1);

    void mySignal2(const QString& text, const QString& text1);

    //槽（Slots）
    //槽是用来响应信号的方法。当一个信号被发出时，与之连接的槽就会被调用。
    //槽可以是任何可调用的函数，且可以执行任何操作，比如更新界面、处理数据或者其他任务。在Qt中，槽可以是普通的成员函数、静态函数，甚至是全局函数。

    //自定义槽
    //在以前版本的Qt中，槽函数必须放到public/private/protected slots:
    //此处的slots是Qt自己扩展的关键字.(不是C++标准中的语法)Qt里广泛使用了元编程技术.(基于代码，生成代码)
    //qmake构建Qt项目的时候，就会调用专门的扫描器，扫描代码中特定的关键字
    //(slots这种)基于关键字自动生成一大堆相关的代码.
    //现在新版本可以不写slots,直接写slots,但是我们为了规范,推荐写上slots
public slots:
    void handleClicked();

public slots:
    void handleMySignal2(const QString& text, int number);

public slots:
    void handleMySignal2(const QString& text, const QString& text1);

private slots:
    void on_MyPushButton_clicked();

    void on_pushButton_clicked();

    void handleTest1();

    void handleTest2();

private:
    Ui::Widget *ui;
    static int _count;
};
#endif // WIDGET_H

//所谓的信号槽，终究要解决的问题，就是响应用户的操作
//信号槽，其实在GUI开发的各种框架中，是一个比较有特色的存在
//其他的GUI开发框架，搞的方式都要更简洁一些
//网页开发(js + dom api)网页开发中响应用户操作，主要就是挂回调函数
//不需要搞一个单独的connect完成上述的信号槽连接
//类似于下面这种
//button.onclick = handle;
//function handle(){}
//这样的话就是一对一
//一个事件，只能对应一个处理函数一个处理函数也只能对应到一个事件上

//Qt信号槽，connect这个机制，设想很美好的
//1）解耦合.把触发用户操作的控件和处理对应用户的操作逻辑解耦合
//2）"多对多"效果,一个信号，可以connect到多个槽函数上,一个槽函数，也可以被多个信号connect
